//! Implementation of the Picture class
/*!
\file Picture.cpp
\author Thomas Pfeiffer
\date 13.11.2012
*/
#include <algorithm>
#include <fstream>
#include <string>

#include "Picture.h"

// Initialization of the sttic const variables
const std::string Picture::XML_HEADER = "<?xml version=\"1.0\"?>";
const std::string Picture::SVG_HEADER = "<svg xmlns=\"http://www.w3.org/2000/svg\">";
const std::string Picture::XML_FOOTER = "</svg>";

Picture::Picture( std::string filename, IShapeFactory * fact ) : 
	mFilename(filename), mShapeFactory(fact) { }

Picture::~Picture()
{
	// free memory of every shape in the list
	std::for_each(mShapes.begin(), mShapes.end(), deleteObject);
}
	
std::string const& Picture::getFileName() const
{
	return mFilename;
}

IShapeFactory * Picture::getFactory() const
{
	return mShapeFactory;
}

void Picture::AddCircle( TPosition const& origin, float const& radius, std::string const& color )
{
	mShapes.push_back(mShapeFactory->createCircle(origin, radius, color));
}

void Picture::AddRectangle( TPosition const& origin, TSize const& dimension, std::string const& color )
{
	mShapes.push_back(mShapeFactory->createRectangle(origin, dimension, color));
}

void Picture::WriteSVG() const
{
	//open the file
	std::ofstream outfile(mFilename);

	//check if file is open
	if(!outfile.is_open()){
		throw std::exception("The file wasn't found or couldn't be opened.");
	}

	// print the svg file header
	outfile << XML_HEADER << std::endl;
	outfile << SVG_HEADER << std::endl;

	// call write for every shape in the list
	for (TShapesConstIterator it = mShapes.begin(); it != mShapes.end(); ++it) {
		(*it)->WriteShape(outfile);
	}

	// print the xml end string
	outfile << XML_FOOTER << std::endl;
}

void Picture::checkSep(std::ifstream & ifs) {
	char sep;
	ifs >> sep;
	if (sep != '|') {
		throw std::exception("character '|' expected...");
	}
}

void Picture::LoadShapes( std::string const& filename )
{
	std::ifstream fin (filename);

	// check if file is open and throw error otherwise
	if (!fin.is_open()) {
		throw std::exception("The file wasn't found or couldn't be opened.");
	}

	char type;

	TPosition origin;
	TSize size;
	float radius;
	std::string color;

	while (fin.good()) {
		fin >> type;   // read the type
		checkSep(fin); // read the seperator

		fin >> origin.x;  // read the x component
		checkSep(fin);    // read the seperator

		fin >> origin.y;  // read the y component
		checkSep(fin);    // read the seperator

		// if rectangle, read width, seperator, height and seperator
		// if circle, read radius and seperator
		// if type is unknown throw an error
		switch (type) {
		case 'R':
			fin >> size.width;
			checkSep(fin);
			fin >> size.height;
			checkSep(fin);
			break;
		case 'C':
			fin >> radius;
			checkSep(fin);
			break;
		default:
			throw std::exception("unknown type of shape specified");
			break;
		}

		fin >> color;  // read the color

		switch (type) {
		case 'R':
			mShapes.push_back(mShapeFactory->createRectangle(origin, size, color));
			break;
		case 'C':
			mShapes.push_back(mShapeFactory->createCircle(origin, radius, color));
			break;
		}
	}
}

